<?php


namespace tmcore\services;

use Cron\CronExpression;
use think\facade\Console;

class CronExpressionService
{

    /**
     * 获取下次执行命令的时间
     * @param string $expression cron表达式
     * @param int $time 上一次的执行时间
     * @return int
     * @throws \Exception
     */
    public function getTimestamp($expression, $time) {
        return (new CronExpression($expression))
            ->getNextRunDate($time)
            ->getTimestamp();
    }

    /**
     * 执行命令
     * @param string $command 执行命令
     * @param array $parameters 传参
     */
    public function cronCall($command, $parameters) {
        if($parameters) {
            Console::call($command, $parameters);
        } else {
            Console::call($command);
        }
    }

    /**
     * 验证cron表达式
     * @param $expression
     * @return bool
     */
    public function verifyExpression($expression) {
        return CronExpression::isValidExpression($expression);
    }

    /**
     * 获取cron表达式
     * @param int $type
     * @param array $data
     * @return string
     */
    public function getCronExpression($type, $data): string
    {
        $min = $data['min'] ?? '*'; //时
        $hour = $data['hour'] ?? '*'; //分
        $day = $data['day'] ?? '*'; //天
        $week = $data['week'] ?? '*'; //星期 周一至日:1-7
        $cron = $data['cron'] ?? '* * * * *'; //表达式

        // * * * * * {分} {时} {日} {月} {周}
        switch ($type) {
            case 1:// 每天N时N分
                $expression = $min . ' ' . $hour . ' ? * *';
                break;

            case 2:// 每隔N天第N时N分
                $expression = $min . ' ' . $hour . ' */' . $day . ' * *';
                break;

            case 3:// 每小时N分钟
                $expression = $min . ' */1' . ' * * *';
                break;

            case 4:// 每隔N小时第N分钟
                $expression = $min . ' */' . $hour . ' * * *';
                break;

            case 5:// 每隔N分钟
                $expression = '*/' . $min . ' * * * *';
                break;

            case 6:// 每星期周几N时N分
                $expression = $min . ' ' . $hour . ' * * ' . $week;
                break;

            case 7:// 每月N日N时N分
                $expression = $min . ' ' . $hour . ' ' . $day . ' * *';
                break;

            default:
                $expression = $cron;
        }

        return $expression;
    }


    /**
     * 获取cron表达式 运行时间点
     * @param string $expression
     * @param int $total
     * @return array
     */
    public function getExpressionRunDates($expression, $total = 4) {
        $cron = new CronExpression($expression);
        $result = json_decode(json_encode($cron->getMultipleRunDates($total)), true);
        $list = [];
        foreach ($result as $k => $v) {
            $list[$k]['num'] = $k + 1;
            $list[$k]['date'] = str_replace('.000000', '', $v['date']);
        }
        $list[] = ['num' => 'n', 'date' => '……'];
        return $list;
    }
}